package org.share.comm.io;

import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 文件相关操作
 * 
 * @author hhm
 *
 */
public class FileUtils {
	// 缓冲区大小
	private static final int BUFFER_SIZE = 20480;

	/**
	 * 保存输入流到文件，inputstream并未关闭
	 * 
	 * @param inputStream
	 * @param toFile
	 */
	public static void streamToFile(InputStream inputStream, File toFile) {
		try {
			FileOutputStream fos = new FileOutputStream(toFile);
			byte[] buf = new byte[BUFFER_SIZE];
			int i;
			while ((i = inputStream.read(buf)) != -1) {
				fos.write(buf, 0, i);
			}
			fos.close();

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 保存输入流到文件，并关闭流
	 * 
	 * @param inputStream
	 * @param toFile
	 */
	public static void streamToFileAndClose(InputStream inputStream, File toFile) {
		try {
			FileOutputStream fos = new FileOutputStream(toFile);
			byte[] buf = new byte[BUFFER_SIZE];
			int i;
			while ((i = inputStream.read(buf)) != -1) {
				fos.write(buf, 0, i);
			}
			fos.close();
			inputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 文件追加写入字符串
	 * 
	 * @param file
	 * @param str
	 */
	public static void appendWrite(File file, String str) {
		try {
			if(!file.exists()){
				file.createNewFile();
			}
			
			// 打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
			FileWriter writer = new FileWriter(file, true);
			writer.write(str);
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取当前目录及子目录下所有文件
	 * 
	 * @param dirPath
	 * @return
	 */
	public static List<File> listAllFiles(String dirPath, FileFilter filter) {
		List<File> list = new ArrayList<>();
		File dir = new File(dirPath);
		if (!dir.exists() || !dir.isDirectory()) {
			return null;
		}

		Queue<File> subDirs = new LinkedBlockingQueue<>();
		for (File f : dir.listFiles(filter)) {
			if (f.isDirectory()) {
				subDirs.offer(f);
			} else {
				list.add(f);
			}
		}
		for (; !subDirs.isEmpty();) {
			File d = subDirs.poll();
			for (File f : d.listFiles(filter)) {
				if (f.isDirectory()) {
					subDirs.offer(f);
				} else {
					list.add(f);
				}
			}
		}

		return list;
	}

	/**
	 * 获取当前目录及子目录下所有文件
	 * 
	 * @param dirPath
	 * @return
	 */
	public static List<File> listAllFiles(String dirPath) {
		List<File> list = new ArrayList<>();
		File dir = new File(dirPath);
		if (!dir.exists() || !dir.isDirectory()) {
			return null;
		}

		Queue<File> subDirs = new LinkedBlockingQueue<>();
		for (File f : dir.listFiles()) {
			if (f.isDirectory()) {
				subDirs.offer(f);
			} else {
				list.add(f);
			}
		}
		for (; !subDirs.isEmpty();) {
			File d = subDirs.poll();
			for (File f : d.listFiles()) {
				if (f.isDirectory()) {
					subDirs.offer(f);
				} else {
					list.add(f);
				}
			}
		}

		return list;
	}

	/**
	 * 目录深度查询包括关键字key的文件
	 * 
	 * @param dirPath
	 * @param key
	 * @return
	 */
	public static List<File> searchFile(String dirPath, final String key) {
		FileFilter filter = new FileFilter() {
			public boolean accept(File file) {
				if (file.isFile()) {
					if (file.getName().toLowerCase().contains(key.toLowerCase())) {
						return true;
					} else {
						return false;
					}
				} else {
					return true;
				}
			}
		};
		return listAllFiles(dirPath, filter);
	}

	public static void main(String[] args) {
		FileUtils.listAllFiles("/Users/hhm/Documents");
	}
}
